((window)=>{
    const PENDING = 'pending'
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'

    function Promise(excutor){
        this.state = PENDING
        this.data = undefined
        this.callbacks = [];

        const self = this;

        //resolve函数
        function resolve(value){
            if(self.state!==PENDING)return
            self.state = FULFILLED
            self.data = value
            if(self.callbacks.length>0){
                setTimeout(() => {
                self.callbacks.forEach(callbackObj=> callbackObj.resolved(value))
                }, 0);
            }
        }

        //reject函数
        function reject(reason){
            if(self.state!==PENDING)return
            self.state = REJECTED
            self.data = reason
            if(self.callbacks.length>0){
                setTimeout(() => {
                    self.callbacks.forEach(callbackObj=> callbackObj.rejected(reason))
                }, 0)
            }
        }

        //捕获执行器抛出的错误
        try {
            excutor(resolve,reject)
        } catch (error) {
           reject(error) 
        }

    }

    //指定成功或者失败的回调，返回一个新的promise
    //onResolved 成功的回调 => 用于得到成功的value
    //onRejected 失败的回调 => 用于得到失败的reason

    //then方法
    Promise.prototype.then = function(onResolved,onRejected){
        const self = this

        //如果onResolved不是函数,指定一个默认函数, 向下传递value
        //如果onRejected不是函数,指定一个默认函数, 向下传递reason

        onResolved = typeof onResolved==='function' ? onResolved : value => value
        onRejected = typeof onRejected==='function' ? onRejected : reason => {throw reason}

        return new Promise((resolve,reject)=>{
            function handle(callback){
                try{
                const result = callback(self.data)
                if(result instanceof Promise){
                    result.then(
                        value => resolve(value),
                        reason =>reject(reason)
                    )

                }else {
                    resolve(result)
                }
            }catch(error){
                reject(error)
            }
        }
        //成功 执行onResolved
        if(self.state ===FULFILLED){
            setTimeout(() => {
                handle(onResolved)
            }, 0);
        }else if(self.state === REJECTED){
        //失败执行onRejected
            setTimeout(() => {
                handle(onRejected)
            }, 0);
        }else{
         //panding状态,等待状态成功，失败，保存onResolved和onRejected
            self.callbacks.push({
                resolve:() => handle(onResolved),
                reject:() =>handle(onRejected)
            })
        }

        //catch方法
        //指定失败的回调，返回一个新的promise
        //本质是then方法的语法糖（简介语法）
        //then(value => value,onRejected)，失败的回调，得到失败的reason
         

        Promise.prototype.catch = function(onRejected){
            return this.then(value => value,onRejected)
        };

        //.reslove方法
        //返回一个成功的promise，value为指定的value
        Promise.resolve = function(value){
            return new Promise((resolve,reject)=>{
                if(Value instanceof Promise){
                    value.then(
                        value=> resolve(value),
                        reason =>reject(reason)
                    )
                }else{
                    resolve(value)
                }
            })
        };

        //.reject方法
        //返回一个失败的promise，reason未指定的reason
        Promise.reject = function(reson){
            return new Promise((resolve,reject)=>{
                reject(reason)
            })
        }

        //.all方法
        //返回一个promise,如果promises都成功,才成功， 成功的value为所有value组成的数组, 只要有一个失败, 那它就失败了
        Promise.all = function (promises){
            //保存所有成功的promise的value的数组
            const values =[]
            let resolvedCount =0
            return new Promise((resolve,reject)=>{
                promises.forEach((p,index)=>{
                    p.then(
                        value =>{
                            values[index] = value
                            resolvedCount += 1;
                            if(resolvedCount===promises.length){
                                resolve(values)
                            }
                        },
                        reason=>{
                            reject(reson)
                        }
                    )
                })
            })
        };



        //.race方法
        //返回一个promise,由第一个完成的promise来决定它的结果
        Promise.race = function(promises){
            return new Promise((resolve,reject)=>{
                promises.forEach(p=>{
                    p.then(
                        value =>resolve(value),
                        reason =>reject(reason),
                    )
                })
            })
        }


        //.allSettled 方法
        //所有完成promise就成功，不因为中途一个失败就失败，成功value是所有promise的value或reason组成的数组
        Promise.allsettled = function(promises){
            const results =[];
            let settledCount = 0
            return new Promise((resolve) =>{
                promises.forEach((p,index)=>{
                    p.then(
                        value =>{
                            //保存当前成功value和成功状态的对象
                            results[index] = {status:'fulfilled',value}
                            settledCount++
                            if(settledCount === promises.length){
                                resolve(results)

                            }
                        },
                        //保存当前失败的reason和失败状态的对象
                        reason =>{
                        results[index] = {status :'rejected',reason}
                        settledCount++;
                        if(settledCount === promises.length){
                            resolve(results)
                        }
                        }
                    )
                })
            })
        };


        //.resolveDelay方法
        //返回一个延迟指定时间才能成功的promise
        Promise.resolveDelay = function(value,delay){
            return new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve(value)
                }, delay);
            })
        }
        //返回一个延迟指定时间才能失败的promise
        Promise.resolveDelay = function(value,delay){
            return new Promise((resolve,reject)=>{
                setTimeout(() => {
                    reject(reason)
                }, delay);
            })
        }
        })
    }

    window.Promise = Promise
})(window)